/** \file    ActivateHoles.cpp
  * \brief   Some mask is specified by active segments; 
  *			 this method activetes also the segments in holes of the mask.
  * \date    2001
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/segm/src/ActivateHoles.cpp,v 1.1 2004/05/20 09:11:46 cscom1r4 Exp $
  */

#include "segm/Segmentation.h"
#include <stack>

inline static void exteriorCheck(int i, BoolArr &exterior, std::stack<int> &extSegments, 
								 Segmentation::segmentIvector &segments)
{
	if(i!=-1 && exterior[i]==false && segments[i].active==false ) {
		exterior[i] = true;
		extSegments.push(i);
	}
}

void Segmentation::activateHoles()
{
	BoolArr exterior( count(), false ); //not mask, not hole
	std::stack<int> extSegments; // exterior segments, to be proccesed
	int x,y,i;
	int w = width();
	int h = height();
	for( x = 0; x != w; ++x ) {
		i = m_segmentCoordMap(x,0);
		exteriorCheck( i, exterior, extSegments, m_segmentIvector );
		i = m_segmentCoordMap(x,h-1);
		exteriorCheck( i, exterior, extSegments, m_segmentIvector );
	}
	for( y = 1; y < h-1; ++y ) {
		i = m_segmentCoordMap(0,y);
		exteriorCheck( i, exterior, extSegments, m_segmentIvector );
		i = m_segmentCoordMap(w-1,y);
		exteriorCheck( i, exterior, extSegments, m_segmentIvector );
	}

	//find entire mask exterior
	while( extSegments.size() > 0 ) {
		i = extSegments.top();
		extSegments.pop();
		IntIntMap::iterator si;
		for( si = m_segmentIvector[i].neighbours.begin(); si != m_segmentIvector[i].neighbours.end(); ++si ) {
			exteriorCheck( si->second, exterior, extSegments, m_segmentIvector );
		}
	}

	//make mask ant its holes active
	for( i = 0; i != count(); ++i ) {
		m_segmentIvector[i].active = !exterior[i];
	}
}
